/**
 * Software License, Version 1.0
 *
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 *
 *
 *Redistribution and use in source and binary forms, with or without
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For
 * further information contact the Community Grids Lab at
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and
 * wherever such third-party acknowledgments normally appear.
 *
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering,
 * shall not be used to endorse or promote products derived from this software
 * without prior written permission from Indiana University.  For written
 * permission, please contact the Advanced Research and Technology Institute
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering,
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 *
 *
 * Indiana University provides no reassurances that the source code provided
 * does not infringe the patent or any other intellectual property rights of
 * any other entity.  Indiana University disclaims any liability to any
 * recipient for claims brought by any other entity based on infringement of
 * intellectual property rights or otherwise.
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS.
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS",
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.samples.nbNative;

/**
 * <p>Title: RobustSubscriberGui</p>
 * <p>Description: Robust RobustSubscriberGui</p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: Pervasive Tech Lab</p>
 * @author Beytullah Yildiz
 * @version 1.0
 */

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Properties;

import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;

import cgl.narada.event.NBEvent;
import cgl.narada.event.TemplateProfileAndSynopsisTypes;
import cgl.narada.matching.Profile;
import cgl.narada.service.ServiceException;
import cgl.narada.service.client.ClientService;
import cgl.narada.service.client.EventConsumer;
import cgl.narada.service.client.NBEventListener;
import cgl.narada.service.client.NBRecoveryListener;
import cgl.narada.service.client.NBRecoveryNotification;
import cgl.narada.service.client.SessionService;
import cgl.narada.service.qos.ConsumerConstraints;

public class RobustSubscriberGui
    extends JPanel
    implements NBEventListener, NBRecoveryListener {
  JTextArea synopsisTextArea;
  JTextField templateTextField;

  JButton recoverButton, createProfileButton;
  JTextArea messageTextArea;
  DefaultListModel recoverListModel;
  private ClientService clientService;
  private EventConsumer consumer;

  int profileType_=1;
  private String moduleName = "RobustSubscriberGui: ";
  /**
   * Consructor
   */
  public RobustSubscriberGui() {
    super(new GridLayout(1, 1));
    int width = 300;
    int height = 200;

    JTabbedPane tabbedPane = new JTabbedPane();

    JComponent panel1 = makeConnectPanel();
    panel1.setPreferredSize(new Dimension(width, height));
    tabbedPane.addTab("Connect", panel1);
    tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);

    JComponent panel2 = makeRecoverPanel();
    panel2.setPreferredSize(new Dimension(width, height));
    tabbedPane.addTab("Recover", panel2);
    tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);

    JComponent panel3 = makeProfilePanel();
    panel3.setPreferredSize(new Dimension(width, height));
    tabbedPane.addTab("Profile", panel3);
    tabbedPane.setMnemonicAt(2, KeyEvent.VK_3);

    JComponent panel4 = makeReceivePanel();
    panel4.setPreferredSize(new Dimension(width, height));
    tabbedPane.addTab("Receive", panel4);
    tabbedPane.setMnemonicAt(3, KeyEvent.VK_3);

    //Add the tabbed pane to this panel.
    add(tabbedPane);
    // to use scrolling tabs.
    tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);

  }

  /**
   * initilize client service
   * @param entityId is client entity id
   */
  public void RobustSubscriber(int entityId) {
    try {
      clientService = SessionService.getClientService(entityId);
      consumer = clientService.createEventConsumer(this);
    }
    catch (ServiceException serviceexception) {
      System.out.println(serviceexception);
    }
  }

  /**
   * Initilize broker communication
   * @param properties
   * @param string
   * @throws ServiceException
   */
  public void initializeBrokerCommunications
      (Properties properties, String string) throws ServiceException {
    clientService.initializeBrokerCommunications(properties, string);
  }

  /**
   * Initilize consumer
   * @param templateId template is
   * @throws ServiceException
   */
  public void initilizeRecoverAndConsumer(int templateId) 
    throws ServiceException {
    long l = consumer.recover(templateId, this);
  }

  /**
   * creates profile
   * @param templateId template id
   * @param profileSynopsis synopsis for consumer
   * @throws ServiceException
   */
  public void createProfile(int templateId, int profileType, 
			    String profileSynopsis) throws ServiceException {
    System.out.println(moduleName + "Profile Type=[" + profileType + "]");
    Profile profile = null;
    if (profileType == TemplateProfileAndSynopsisTypes.INTEGER) {
      System.out.println(moduleName + "Creating Integer Profile ...");
      Integer integerSynopsis = new Integer(Integer.parseInt(profileSynopsis));
      System.out.println(moduleName + integerSynopsis );
      profile = clientService.createProfile(profileType, integerSynopsis);
      
    } else {
      profile = clientService.createProfile(profileType, profileSynopsis);
    }
    
    ConsumerConstraints consumerconstraints
      = consumer.createConsumerConstraints(profile);
    consumerconstraints.setReceiveReliably(templateId);
    consumer.subscribeTo(profile, consumerconstraints);
  }

  /**
   * listens the comming messages
   * @param nbevent is the comming message package
   */

  public void onEvent(NBEvent nbevent) {

    String st = new String(nbevent.getContentPayload());

    System.out.println("\n\n\n\n" + moduleName + "Received NBEvent =>"
                       + new String(nbevent.getContentPayload()) + "\n\n");
    messageTextArea.append(st + "\n");
  }

  /**
   * listens comming notification for recovery
   * @param nbrecoverynotification
   */

  public void onRecovery(NBRecoveryNotification nbrecoverynotification) {
    System.out.println("\n\n\n\n" + moduleName + nbrecoverynotification
                       + "\n\n");

    Profile[] profilesarray = consumer.getListOfManagedProfiles();
    int arraylenght = profilesarray.length;
    recoverListModel.clear();
    System.out.println("arraylenght :" + arraylenght);
    if (arraylenght > 0) {
      recoverListModel.addElement("Automatically Registered to");
      for (int i = 0; i < arraylenght; i++) {
        String profile = profilesarray[i].toString();
        System.out.println("profileid :" + profile);
        recoverListModel.addElement(profile);
      }

    }
  }

  /**
   * create properties
   * @param hostname  host name
   * @param portnumber port number
   * @return properties
   */

  public Properties createProperties(String hostname, String portnumber) {
    Properties properties = new Properties();
    properties.put("hostname", hostname);
    properties.put("portnum", portnumber);
    return properties;
  }

  /**
   * Creates Connect Tabbed Pane
   * @return frame
   */

  protected JComponent makeConnectPanel() {
    //System.out.println("makeConnectPanel");
    JPanel panel = new JPanel(false);
    panel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    JLabel entityLabel = new JLabel("Entity Id : ");
    final JTextField entityTextField = new JTextField("4444", 10);
    entityTextField.setEditable(false);
    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(entityLabel, c);
    c.gridx = 3;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 2;
    panel.add(entityTextField, c);

    JLabel hostLabel = new JLabel("Host name : ");
    final JTextField hostTextField = new JTextField(20);
    c.gridx = 0;
    c.gridy = 3;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(hostLabel, c);
    c.gridx = 3;
    c.gridy = 3;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(hostTextField, c);

    JLabel portLabel = new JLabel("Port number : ");
    final JTextField portTextField = new JTextField(10);
    c.gridx = 0;
    c.gridy = 5;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(portLabel, c);
    c.gridx = 3;
    c.gridy = 5;
    c.gridwidth = 1;
    c.gridheight = 2;
    panel.add(portTextField, c);

    final JButton connectButton = new JButton("Connect");
    connectButton.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {
        String stentity = entityTextField.getText();
        int entityid_ = new Integer(stentity).intValue();
        String hostname_ = hostTextField.getText();
        String portnr = portTextField.getText();
        int portnumber_ = new Integer(portnr).intValue();

        RobustSubscriber(entityid_);
        Properties properties = createProperties(hostname_, portnr);
        try {
          initializeBrokerCommunications(properties, "niotcp");
          recoverButton.setEnabled(true);
          connectButton.setEnabled(false);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

        System.out.println("entity id :" + entityid_);
        System.out.println("host name : " + hostname_);
        System.out.println("port : " + portnumber_);

      }
    }

    );

    c.gridx = 2;
    c.gridy = 10;
    c.gridwidth = 4;
    c.gridheight = 2;

    panel.add(connectButton, c);

    return panel;
  }

  /**
   * creates Tabbed Tamplate info Pane
   * @return frame
   */
  protected JComponent makeRecoverPanel() {
    JPanel panel = new JPanel(false);
    panel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    recoverListModel = new DefaultListModel();

    JList recoverList = new JList(recoverListModel);
    recoverList.setVisibleRowCount(6);
    recoverList.setAutoscrolls(true);
    recoverList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    recoverList.setSelectedIndex( -1);
    JScrollPane topicListScrollPane = new JScrollPane(recoverList);
    topicListScrollPane.setPreferredSize(new Dimension(250, 80));

    c.gridx = 0;
    c.gridy = 10;
    c.gridwidth = 4;
    c.gridheight = 8;
    panel.add(topicListScrollPane, c);

    JLabel templateLabel = new JLabel("Template Id :");
    final JTextField templateTextField = new JTextField(10);
    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 2;
    c.gridheight = 4;
    panel.add(templateLabel, c);
    c.gridx = 2;
    c.gridy = 0;
    c.gridwidth = 2;
    c.gridheight = 4;
    panel.add(templateTextField, c);

    recoverButton = new JButton("    Recover    ");

    recoverButton.setEnabled(false);
    recoverButton.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {
        String sttemp = templateTextField.getText();
        int templid_ = new Integer(sttemp).intValue();

        try {
          initilizeRecoverAndConsumer(templid_);

          //createProfileButton.setEnabled(false);
        }
        catch (Exception ex) {
          System.out.println("Recovery request problems " + ex.toString());
        }

        //System.out.println("template id :" + templid_);

      }

    }

    );

    c.gridx = 2;
    c.gridy = 5;
    c.gridwidth = 2;
    c.gridheight = 2;
    panel.add(recoverButton, c);

    return panel;

  }

  protected JComponent makeRadioButtonPanel() {

    JRadioButton stringRadioButton, xmlRadioButton;
    JRadioButton integerRadioButton, regularExpRadioButton;
    JRadioButton tagValueExpRadioButton;
    ButtonGroup buttonGroup;
    JLabel templateTypeLabel;

    JPanel panel = new JPanel(false);
    panel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    templateTypeLabel = new JLabel("Profile Type :");

    stringRadioButton = new JRadioButton("String   ");
    stringRadioButton.setSelected(true);
    xmlRadioButton = new JRadioButton("XML");
    integerRadioButton = new JRadioButton("Integer");
    regularExpRadioButton = new JRadioButton("Regular Expression");
    tagValueExpRadioButton = new JRadioButton("Tag Value Pairs   ");

    buttonGroup = new ButtonGroup();
    buttonGroup.add(stringRadioButton);
    buttonGroup.add(xmlRadioButton);
    buttonGroup.add(integerRadioButton);
    buttonGroup.add(regularExpRadioButton);
    buttonGroup.add(tagValueExpRadioButton);

//Register a listener for the radio buttons.
    stringRadioButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        templateTextField.setText("11111");
        synopsisTextArea.setText("Movies/Casablanca");
        profileType_=TemplateProfileAndSynopsisTypes.STRING;
      }
    }
    );

    String xml = "/menu/softdrinks[prics>1.8]";
    final String xml_ = xml;

    xmlRadioButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        templateTextField.setText("22222");
        synopsisTextArea.setText(xml_);
        profileType_=TemplateProfileAndSynopsisTypes.XML;
      }
    }
    );

    integerRadioButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        templateTextField.setText("33333");
        synopsisTextArea.setText("123456789");
        profileType_=TemplateProfileAndSynopsisTypes.INTEGER;
      }
    }
    );

    regularExpRadioButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        templateTextField.setText("44444");
        synopsisTextArea.setText("[Tt]he [A-Z,a-z]brown");
        profileType_=TemplateProfileAndSynopsisTypes.REGULAR_EXPRESSIONS;
      }
    }
    );

    tagValueExpRadioButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        templateTextField.setText("55555");
        synopsisTextArea.setText("Sport=NBA, Team=Bulls, Player=Jordan");
        profileType_=TemplateProfileAndSynopsisTypes.TAG_VALUE_PAIRS;
      }
    }
    );

    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(templateTypeLabel, c);

    c.gridx = 1;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(stringRadioButton, c);

    c.gridx = 2;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(xmlRadioButton, c);

    c.gridx = 1;
    c.gridy = 1;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(integerRadioButton, c);

    c.gridx = 2;
    c.gridy = 1;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(regularExpRadioButton, c);

    c.gridx = 2;
    c.gridy = 2;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(tagValueExpRadioButton, c);

    return panel;
  }

  /**
   * creates Tabbed Profile Pane
   * @return frame
   */

  protected JComponent makeProfilePanel() {

    JPanel panel = new JPanel(false);
    panel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(makeRadioButtonPanel(), c);

    JLabel tamplateLabel = new JLabel("Template Id : ");
    templateTextField = new JTextField("11111", 18);
    c.gridx = 0;
    c.gridy = 2;
    c.gridwidth = 1;
    c.gridheight = 1;

    panel.add(tamplateLabel, c);
    c.gridx = 2;
    c.gridy = 2;
    c.gridwidth = 2;
    c.gridheight = 1;

    panel.add(templateTextField, c);

    JLabel synopsisLabel = new JLabel("Subscription : ");
    synopsisTextArea = new JTextArea("Movies/Casablanca", 4, 18);
    JScrollPane messageScroll = new JScrollPane(synopsisTextArea,
                                                JScrollPane.
                                                VERTICAL_SCROLLBAR_AS_NEEDED,
                                                JScrollPane.
                                                HORIZONTAL_SCROLLBAR_AS_NEEDED);

    c.gridx = 0;
    c.gridy = 3;
    c.gridwidth = 1;
    c.gridheight = 1;

    panel.add(synopsisLabel, c);
    c.gridx = 2;
    c.gridy = 3;
    c.gridwidth = 2;
    c.gridheight = 2;

    panel.add(messageScroll, c);

    createProfileButton = new JButton("Create Profile");
    //createProfileButton.setEnabled(false);
    createProfileButton.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {
        String sttemp = templateTextField.getText();
        int templid_ = new Integer(sttemp).intValue();
        String tempsynopsis_ = synopsisTextArea.getText();

        try {

          createProfile(templid_, profileType_, tempsynopsis_);

        }
        catch (Exception ex) {
          System.out.println(moduleName + "You have already been subscribed" 
			     + ex.toString());

        }

      }
    }

    );

    c.gridx = 2;
    c.gridy = 5;
    c.gridwidth = 1;
    c.gridheight = 1;

    panel.add(createProfileButton, c);

    return panel;
  }

  /**
   * creates Tabbed Receive Pane
   * @return frame
   */

  protected JComponent makeReceivePanel() {

    JPanel panel = new JPanel(false);
    panel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    JLabel messageLabel = new JLabel("Message : ");
    messageTextArea = new JTextArea(6, 25);
    messageTextArea.setLineWrap(true);
    JScrollPane messageScroll = new JScrollPane(messageTextArea,
                                                JScrollPane.
                                                VERTICAL_SCROLLBAR_AS_NEEDED,
                                                JScrollPane.
                                                HORIZONTAL_SCROLLBAR_AS_NEEDED);

    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(messageLabel, c);
    c.gridx = 3;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 2;
    panel.add(messageScroll, c);

    return panel;
  }

  /**
   * Create the GUI and show it.  For thread safety,
   * this method should be invoked from the
   * event-dispatching thread.
   */
  private static void createAndShowGUI() {
    //Make sure we have nice window decorations.
    JFrame.setDefaultLookAndFeelDecorated(true);

    //Create and set up the window.
    JFrame frame = new JFrame("Rebust Subscriber");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Create and set up the content pane.
    JComponent newContentPane = new RobustSubscriberGui();
    newContentPane.setOpaque(true); //content panes must be opaque
    frame.getContentPane().add(new RobustSubscriberGui(),
                               BorderLayout.CENTER);

    //Display the window.
    //frame.pack();
    frame.setBounds(50, 50, 450, 300);
    frame.setVisible(true);
  }

  private void jbInit() throws Exception {

  }

  public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });

  }

}
